package com.yhy.wxzn.wcs.device.rgv.bean;

import com.yhy.wxzn.wcs.device.rgv.enums.Action;
import com.yhy.wxzn.wcs.device.rgv.enums.NodeStatus;
import com.yhy.wxzn.wcs.device.rgv.enums.NodeType;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class Node extends Coord implements Comparable<Node> {
    public List<Action> actions = new ArrayList<>();
    private Action resAction;
    private NodeStatus nodeStatus;
    private NodeType nodeType;

    private Boolean up;

    private Boolean down;

    private Boolean left;

    private Boolean right;


    private Node parent; // 父结点
    private int G; // G：是个准确的值，是起点到当前结点的代价
    private int H; // H：是个估值，当前结点到目的结点的估计代价

    public static final int COST = 1;//单元格的花费
    public static final int reversingCost = 2;//换向单元格的花费


    private String groundCode;
    private Integer offsetX;
    private Integer offsetY;

    public Node(){}

    public Node(int x, int y, int z) {
        super(x, y, z);
    }

    public Node(Coord coord) {
        super(coord.getX(), coord.getY(), coord.getZ());
    }


    /**
     * 路径规划用
     * @param coord
     * @param nodeType
     * @param nodeStatus
     * @param up
     * @param down
     * @param left
     * @param right
     */
    public Node(Coord coord, NodeType nodeType, NodeStatus nodeStatus, Boolean up, Boolean down, Boolean left,
                Boolean right) {
        super(coord.getX(), coord.getY(), coord.getZ());
        this.nodeStatus = nodeStatus;
        this.nodeType = nodeType;
        this.up = up;
        this.down = down;
        this.left = left;
        this.right = right;
    }

    public Node(Coord coord, Node parent, int g, int h) {
        this(coord);
        this.parent = parent;
        this.G = g;
        this.H = h;
    }



    //使用treeMap,当两者值相同会覆盖原value
    //treeMap和HashMap一起使用该方法引起的BUG，当map单节点长度超过16产生红黑树，会使用compareTo进行比较获取值，为了使用treemap去掉了相同值的情况，会导致红黑树无法正常获取值
    //综合来说，使用hashmap+堆的方式解决
    @Override
    public int compareTo(@NotNull Node o) {
        if (o == null) return -1;
        if (G + H > o.G + o.H)
            return 1;
        if (G + H < o.G + o.H)
            return -1;
         return 0;
    }


    public static Node getUpNode(Node n){
        return new Node(n.getX() - 1,n.getY(),n.getZ());
    }
    public static Node getDownNode(Node n){
        return new Node(n.getX() + 1,n.getY(),n.getZ());
    }
    public static Node getLeftNode(Node n){
        return new Node(n.getX(),n.getY() - 1,n.getZ());
    }
    public static Node getRightNode(Node n){
        return new Node(n.getX(),n.getY() + 1,n.getZ());
    }

    public static Node parseNode(String str){
       return new Node(parseCoord(str));
    }

    public List<Action> getActions() {
        return actions;
    }

    public void setActions(List<Action> actions) {
        this.actions = actions;
    }

    public Action getResAction() {
        return resAction;
    }

    public void setResAction(Action resAction) {
        this.resAction = resAction;
    }

    public NodeStatus getNodeStatus() {
        return nodeStatus;
    }

    public void setNodeStatus(NodeStatus nodeStatus) {
        this.nodeStatus = nodeStatus;
    }

    public NodeType getNodeType() {
        return nodeType;
    }

    public void setNodeType(NodeType nodeType) {
        this.nodeType = nodeType;
    }

    public Boolean getUp() {
        return up;
    }

    public void setUp(Boolean up) {
        this.up = up;
    }

    public Boolean getDown() {
        return down;
    }

    public void setDown(Boolean down) {
        this.down = down;
    }

    public Boolean getLeft() {
        return left;
    }

    public void setLeft(Boolean left) {
        this.left = left;
    }

    public Boolean getRight() {
        return right;
    }

    public void setRight(Boolean right) {
        this.right = right;
    }


    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public int getG() {
        return G;
    }

    public void setG(int g) {
        G = g;
    }

    public int getH() {
        return H;
    }

    public void setH(int h) {
        H = h;
    }

    public String getGroundCode() {
        return groundCode;
    }

    public void setGroundCode(String groundCode) {
        this.groundCode = groundCode;
    }

    public Integer getOffsetX() {
        return offsetX;
    }

    public void setOffsetX(Integer offsetX) {
        this.offsetX = offsetX;
    }

    public Integer getOffsetY() {
        return offsetY;
    }

    public void setOffsetY(Integer offsetY) {
        this.offsetY = offsetY;
    }
}


